/*
 * extended_buffer.cxx
 *
 *  Created on: Apr 4, 2011
 *      Author: whisper
 */

#include "crypto/extended_buffer.h"

/**
 * @brief Dynamic push and pop Buffer for audio samples
 * @author Bernhard Schildendorfer
 *
 * CExtendedBuffer provides a fixed length byte-buffer which indicates if it's full.
 *
 * CExtendedBuffer contains two FIFO Queues, which are called input-buffer and output-buffer.
 * Data which is written to CExtendedBuffer is stored to the input-buffer, data which is
 * read from CExtendedBuffer is read from the output-buffer. To transfer data between them,
 * the method processBuffer() needs to be called. Manipulation to the buffer is
 * possible via the byte* of isBufferReady();
 *
 */
//fixed size of the buffer
CExtendedBuffer::CExtendedBuffer() {
	//mInputBuffer = new queue<double>();
	//mOutputBuffer = new queue<double>();
}




CExtendedBuffer::~CExtendedBuffer() {
	// TODO Auto-generated destructor stub
	// nothing to delete yet
}






//store pCount bytes in the Buffer.
//return: - if the buffer is full, a  byte pointer is returned to the beginning of the full buffer
//        - null if buffer is not full
void CExtendedBuffer::write(const double* pData , unsigned int pCount){
	for(unsigned int i=0;i<pCount;i++){
		mBuffer.push_back(pData[i]);
	}
	return;
}



//receive and remove pCount elements from the output buffer.
//If there is less data in the buffer than requested by pCount, additional zeros will be written
double* CExtendedBuffer::read(unsigned int pCount){
	if(pCount==0)
		return NULL;
	if(pCount>mBuffer.size())
		return NULL;
	double* data = new double[pCount];
	list<double>::iterator it;

	unsigned int i=0;
	for ( it=mBuffer.begin(); i<pCount; it++ ){
	    data[i]=*it;
	    i++;
	}

	return data;
}

void CExtendedBuffer::copy(double* pDestination, unsigned int pCount){
	if(pCount==0 || pDestination==NULL)
		return;

	unsigned int lDiff = 0;

	if(pCount>mBuffer.size())
		lDiff=pCount-mBuffer.size();

	while(lDiff>0){
		*pDestination=0;
		pDestination++;
		lDiff--;
		pCount--;
	}

	list<double>::iterator it;

	unsigned int i=0;
	for (it=mBuffer.begin(); i<pCount; it++ ){
		*pDestination=*it;
		i++;
		pDestination++;
	}


}


void CExtendedBuffer::remove(unsigned int pCount){
	if(pCount==0)
			return;

	for(unsigned int i=0;i<pCount && mBuffer.size()>0;i++){
		mBuffer.pop_front();
	}
}

unsigned int CExtendedBuffer::size(){
	return mBuffer.size();
}



